#!/bin/bash -x
set -x
ProgName=$(basename $0)
BaseDir=$(dirname $(readlink -f "$0"))
LocalAppHome=$(dirname $BaseDir)
SYSOM_INSTALL_LOG=$LOG_HOME/sysom_install.log

####################################################################################################################
# Helper functions
####################################################################################################################

red() {
    printf '\33[1;31m%b\n\33[0m' "$1"
}

green() {
    printf '\33[1;32m%b\n\33[0m' "$1"
}

install_new_scripts() {
    green "now install new scripts ..................."
    if [ "${LocalAppHome}" != "${APP_HOME}" ]; then
        rm -rf $SCRIPT_HOME
        cp -r ${LocalAppHome}/script $SCRIPT_HOME
    fi
}

update_global_config() {
    sed "s/SERVER_LOCAL_IP: 127.0.0.1/SERVER_LOCAL_IP: $SERVER_LOCAL_IP/g" -i ${SYSOM_CONF}
    sed "s/SERVER_PUBLIC_IP: 127.0.0.1/SERVER_PUBLIC_IP: $SERVER_PUBLIC_IP/g" -i ${SYSOM_CONF}
    sed "s/SERVER_PORT: 80/SERVER_PORT: $SERVER_PORT/g" -i ${SYSOM_CONF}
    sed "s/global_root_path \/usr\/local\/sysom/global_root_path $APP_HOME/g" -i ${SYSOM_CONF}

    # MySQL
    if [ $DB_MYSQL_HOST ]; then
        sed "/mysql/,/host/s/host: localhost/host: $DB_MYSQL_HOST/g" -i ${SYSOM_CONF}
    fi
    if [ $DB_MYSQL_PORT ]; then
        sed "/mysql/,/port/s/port: 3306/port: $DB_MYSQL_PORT/g" -i ${SYSOM_CONF}
    fi
    if [ $DB_MYSQL_USERNAME ]; then
        sed "/mysql/,/user/s/user: sysom/user: $DB_MYSQL_USERNAME/g" -i ${SYSOM_CONF}
    fi
    if [ $DB_MYSQL_PASSWORD ]; then
        sed "/mysql/,/password/s/password: sysom_admin/password: $DB_MYSQL_PASSWORD/g" -i ${SYSOM_CONF}
    fi
    if [ $DB_MYSQL_DATABASE ]; then
        sed "/mysql/,/database/s/database: sysom/database: $DB_MYSQL_DATABASE/g" -i ${SYSOM_CONF}
    fi

    # Redis
    if [ $REDIS_HOST ]; then
        sed "/redis:/,/host/s/host: localhost/host: $REDIS_HOST/g" -i ${SYSOM_CONF}
    fi
    if [ $REDIS_PORT ]; then
        sed "/redis:/,/port/s/port: 6379/port: $REDIS_PORT/g" -i ${SYSOM_CONF}
    fi
    if [ $REDIS_USERNAME ]; then
        sed "/redis:/,/username/s/username:/username: $REDIS_USERNAME/g" -i ${SYSOM_CONF}
    fi
    if [ $REDIS_PASSWORD ]; then
        sed "/redis:/,/password/s/password:/password: $REDIS_PASSWORD/g" -i ${SYSOM_CONF}
    fi

    ###update local timezone###
    local_timezone=$(timedatectl status | grep "Time zone" | awk '{print $3}')
    green "current timezone is : $local_timezone"
    if [ "$local_timezone" == "" ]; then
        echo "get time zone fail, use default time zone Asia/Shanghai"
    else
        sed "s;Asia/Shanghai;$local_timezone;g" -i ${SYSOM_CONF}
    fi
}

ensure_config_exist() {
    if [ ! -f "$SYSOM_CONF" ]; then
        green "old $SYSOM_CONF not exist, now init and set local configure .............."
        cp ${LocalAppHome}/conf/config.yml $SYSOM_CONF
        update_global_config
    else
        green "old $SYSOM_CONF exist, not update configure .............."
    fi
}

do_install_microservices() {
    mkdir -p ${MICROSERVICE_HOME}
    mkdir -p ${MICROSERVICE_SCRIPT_HOME}
    local_microservice_dir=${LocalAppHome}/sysom_server
    if [ ! -d ${local_microservice_dir} ]; then
        local_microservice_dir=${LocalAppHome}/server
    fi
    local_script_dir=$BaseDir/server
    target=$1
    targets=(${target//,/ })
    for target in ${targets[*]}; do
        for service in $(ls ${local_microservice_dir} | grep ${target}); do
            local_service_dir=${local_microservice_dir}/${service}
            local_service_install_script_dir=${local_script_dir}/${service}
            service_dir=${MICROSERVICE_HOME}/${service}
            service_install_script_dir=${MICROSERVICE_SCRIPT_HOME}/${service}
            if [ "$LocalAppHome" != "$APP_HOME" ]; then
                rm -rf ${service_dir}
                cp -r ${local_service_dir} ${service_dir}
                rm -rf ${service_install_script_dir}
                cp -r ${local_service_install_script_dir} ${service_install_script_dir}
            fi

            ################################################################################################
            # Service conf initial
            ################################################################################################
            pushd ${service_dir}
            # update microservice common.py, replace {BASE_DIR.parent.parent}/conf/config.yml to ${SYSOM_CONF}
            if [ -f "${service_dir}/conf/common.py" ]; then
                sed -i "s;{BASE_DIR.parent.parent}/conf/config.yml;/etc/sysom/config.yml;g" ${service_dir}/conf/common.py
            fi
            # update fastapi based microservice alembic/env.py, replace {BASE_DIR.parent.parent}/conf/config.yml to ${SYSOM_CONF}
            if [ -f "${service_dir}/alembic/env.py" ]; then
                sed -i "s;{BASE_DIR.parent.parent}/conf/config.yml;/etc/sysom/config.yml;g" ${service_dir}/alembic/env.py
            fi
            # update microservice gunicorn.py replace /var/log/sysom to ${LOG_HOME}
            if [ -f "${targetservice_dir_dir}/conf/gunicorn.py" ]; then
                sed -i "s;/var/log/sysom;${LOG_HOME};g" ${service_dir}/conf/gunicorn.py
            fi
            popd

            ################################################################################################
            # Perform service initial script
            ################################################################################################

            pushd ${service_install_script_dir}
            # update *.ini replace /var/log/sysom to ${LOG_HOME}
            for ini_conf in $(ls sysom-*.ini); do
                sed -i "s;/var/log/sysom;${LOG_HOME};g" ${service_install_script_dir}/${ini_conf}
            done

            green "$service_install_script_dir installing..................................."
            if [ ! -f "${service_install_script_dir}/install.sh" ]; then
                popd
                continue
            fi
            bash -x ${service_install_script_dir}/install.sh
            if [ $? -ne 0 ]; then
                red "$service_install_script_dir install fail, please check..................................."
                red "sysom install failed, exit 1"
                exit 1
            fi
            popd
        done
    done
}

do_install_environment() {
    mkdir -p ${ENVIRONMENT_HOME}
    local_environment_dir=${LocalAppHome}/environment
    target=$1
    targets=(${target//,/ })
    for target in ${targets[*]}; do
        for env in $(ls ${local_environment_dir} | grep ${target}); do
            if [ "$LocalAppHome" != "$APP_HOME" ]; then
                # Copy env dir to deploy path if need
                cp -r $local_environment_dir/${env} $ENVIRONMENT_HOME/${env}
            fi

            target_dir=${ENVIRONMENT_HOME}/${env}
            if [ ! -d "${target_dir}" ] || [ ! -f "${target_dir}/install.sh" ]; then
                continue
            fi

            pushd ${target_dir}
            green "$target_dir installing..................................."
            bash -x ${target_dir}/install.sh
            if [ $? -ne 0 ]; then
                red "$target_dir install fail, please check..................................."
                red "sysom install failed, exit 1"
                exit 1
            fi
            popd
        done

    done
}

do_install_deps() {
    mkdir -p ${DEPS_HOME}
    local_deps_dir=${LocalAppHome}/deps
    target=$1
    targets=(${target//,/ })
    for target in ${targets[*]}; do
        for dep in $(ls ${local_deps_dir} | grep ${target}); do
            if [ "$LocalAppHome" != "$APP_HOME" ]; then
                # Copy dep dir to deploy path if need
                cp -r $local_deps_dir/${dep} $DEPS_HOME/${dep}
            fi

            target_dir=${DEPS_HOME}/${dep}
            if [ ! -d "${target_dir}" ] || [ ! -f "${target_dir}/install.sh" ]; then
                continue
            fi

            pushd ${target_dir}
            green "$target_dir installing..................................."
            bash -x ${target_dir}/install.sh
            if [ $? -ne 0 ]; then
                red "$target_dir install fail, please check..................................."
                red "sysom install failed, exit 1"
                exit 1
            fi
            popd
        done

    done
}

####################################################################################################################
# Subcommands
####################################################################################################################

sub_help() {
    echo "Usage: $ProgName <subcommand> [options]"
    echo "Subcommands:"
    echo "    all     Install all modules"
    echo "    env   [ALL | <base_env_name>]        Install all enviroment or specific enviroment"
    echo "          Example: $ProgName env env"
    echo "          Example: $ProgName env sdk"
    echo "    deps  [ALL | <deps_name>]            Install all deps or specific dep"
    echo "          Example: $ProgName dep mysql"
    echo "          Example: $ProgName dep grafana"
    echo "    ms    [ALL | <service_name>]         Install all microservices or specific microservice"
    echo "          Example: $ProgName ms sysom_diagnosis"
    echo ""
    echo "For help with each subcommand run:"
    echo "$ProgName <subcommand> -h|--help"
    echo ""
}

sub_ALL() {
    sub_deps ALL
    sub_env ALL
    sub_ms ALL
    sub_web
}

sub_all() {
    sub_ALL
}

sub_env() {
    sub_environment $@
}

# -> env + local_services
sub_environment() {
    target=$1
    if [ "$target" == "ALL" ]; then
        do_install_environment $DEPLOY_ENV_LIST
    else
        # Install specific microservices
        do_install_environment $target
    fi
}

sub_ms() {
    sub_microservice $@
}

sub_server() {
    sub_microservice $@
}

# All microservices
sub_microservice() {
    target=$1
    if [ "$target" == "ALL" ]; then
        echo !!!!$DEPLOY_SERVER_LIST
        do_install_microservices $DEPLOY_SERVER_LIST
    else
        # Install specific microservices
        do_install_microservices $target
    fi
}

sub_deps() {
    target=$1
    if [ "$target" == "ALL" ]; then
        do_install_deps $DEPLOY_DEPS_LIST
    else
        # Install specific microservices
        do_install_deps $target
    fi
}

# Install web
sub_web() {
    local_web_home=${LocalAppHome}/sysom_web
    if [ ! -d ${local_web_home} ]; then
        local_web_home=${LocalAppHome}/web
    else
        rm -rf ${WEB_HOME}
    fi

    if [ "${local_web_home}" != "${WEB_HOME}" ]; then
        pushd ${local_web_home}
        if [ -f "index.html" ]; then
            # dist
            cp -r ${local_web_home} ${WEB_HOME}
        else
            # source
            yarn
            yarn build
            cp -r dist ${WEB_HOME}
        fi
        mkdir -p ${WEB_HOME}/download
        popd
    fi
}

subcommand=$1
case $subcommand in
"" | "-h" | "--help")
    sub_help
    ;;
*)
    install_new_scripts
    ensure_config_exist
    shift
    sub_${subcommand} $@ | tee -a ${SYSOM_INSTALL_LOG} || exit 1
    if [ $? = 127 ]; then
        echo "Error: '$subcommand' is not a known subcommand." >&2
        echo "       Run '$ProgName --help' for a list of known subcommands." >&2
        exit 1
    fi
    ;;
esac
